package com.lzc.jobrecomendbackend.service.recommendation.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lzc.jobrecomendbackend.model.Job;
import com.lzc.jobrecomendbackend.model.education.EducationDistributionVO;
import com.lzc.jobrecomendbackend.model.recommendation.CareerAdviceRequest;
import com.lzc.jobrecomendbackend.model.recommendation.CareerAdviceVO;
import com.lzc.jobrecomendbackend.model.recommendation.LearningResourceRequest;
import com.lzc.jobrecomendbackend.model.recommendation.LearningResourceVO;
import com.lzc.jobrecomendbackend.model.recommendation.PageAdviceRequest;
import com.lzc.jobrecomendbackend.model.recommendation.PageAdviceVO;
import com.lzc.jobrecomendbackend.model.salary.CityCompareVO;
import com.lzc.jobrecomendbackend.model.salary.SalaryDistributionVO;
import com.lzc.jobrecomendbackend.model.skills.SkillCombinationItem;
import com.lzc.jobrecomendbackend.model.skills.SkillCombinationVO;
import com.lzc.jobrecomendbackend.model.skills.SkillDistributionVO;
import com.lzc.jobrecomendbackend.model.skills.SkillItem;
import com.lzc.jobrecomendbackend.repository.JobRepository;
import com.lzc.jobrecomendbackend.service.education.EducationService;
import com.lzc.jobrecomendbackend.service.recommendation.RecommendationService;
import com.lzc.jobrecomendbackend.service.salary.SalaryService;
import com.lzc.jobrecomendbackend.service.skills.SkillService;
import com.lzc.jobrecomendbackend.utils.LLMService;
import com.lzc.jobrecomendbackend.utils.SkillExtractor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 智能推荐服务实现类
 */
@Service
public class RecommendationServiceImpl implements RecommendationService {

    @Autowired
    private JobRepository jobRepository;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private LLMService llmService;

    @Autowired
    private SkillService skillService;

    @Autowired
    private SalaryService salaryService;

    @Autowired
    private EducationService educationService;

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public CareerAdviceVO getCareerAdvice(CareerAdviceRequest request) {
        long startTime = System.currentTimeMillis();
        System.out.println("========== 开始获取职业建议 ==========");
        
        if (request.getSkills() == null || request.getSkills().isEmpty() ||
                request.getEducation() == null || request.getExperience() == null) {
            throw new IllegalArgumentException("技能、学历和工作经验为必填项");
        }

        // 1. 获取市场数据作为分析基础
        List<String> marketTrends = getMarketTrends(request);
        System.out.println("获取到市场趋势: " + marketTrends);
        
        // 2. 构建提示词
        String prompt = buildCareerAdvicePrompt(request, marketTrends);
        System.out.println("构建的提示词长度: " + prompt.length() + " 字符");
        
        // 3. 调用大模型获取建议
        String llmResponse = llmService.sendPrompt(prompt);
        
        // 4. 解析大模型响应，构建结构化数据
        CareerAdviceVO result = parseCareerAdviceResponse(llmResponse, request);
        
        long endTime = System.currentTimeMillis();
        System.out.println("职业建议生成完成，耗时: " + (endTime - startTime) + "ms");
        
        return result;
    }

    @Override
    public LearningResourceVO getLearningResources(LearningResourceRequest request) {
        long startTime = System.currentTimeMillis();
        System.out.println("========== 开始获取学习资源 ==========");
        
        if (request.getSkillName() == null || request.getSkillName().isEmpty()) {
            throw new IllegalArgumentException("技能名称为必填项");
        }

        // 1. 构建提示词
        String prompt = buildLearningResourcePrompt(request);
        System.out.println("构建的提示词长度: " + prompt.length() + " 字符");
        
        // 2. 调用大模型获取资源建议
        String llmResponse = llmService.sendPrompt(prompt);
        
        // 3. 解析大模型响应，构建结构化数据
        LearningResourceVO result = parseLearningResourceResponse(llmResponse, request);
        
        long endTime = System.currentTimeMillis();
        System.out.println("学习资源生成完成，耗时: " + (endTime - startTime) + "ms");
        
        return result;
    }
    
    @Override
    public PageAdviceVO getPageSpecificAdvice(PageAdviceRequest request) {
        long startTime = System.currentTimeMillis();
        System.out.println("========== 开始获取" + request.getPageType() + "页面智能建议 ==========");
        
        if (request.getPageType() == null || request.getPageType().isEmpty()) {
            throw new IllegalArgumentException("页面类型不能为空");
        }
        
        Map<String, Object> data = request.getData();
        if (data == null) {
            data = new HashMap<>();
        }
        
        // 如果是空数据，说明需要从对应的服务获取当前页面数据
        if (data.isEmpty()) {
            // 根据页面类型获取对应的页面数据
            data = getPageData(request.getPageType());
            request.setData(data);
        }
        
        // 1. 根据页面类型构建提示词
        String prompt = buildPromptByPageType(request);
        System.out.println("构建的提示词长度: " + prompt.length() + " 字符");
        
        // 2. 调用大模型获取建议
        String llmResponse = llmService.sendPrompt(prompt);
        
        // 3. 解析回复并格式化为统一的PageAdviceVO对象
        PageAdviceVO result = parseAdviceResponse(llmResponse, request.getPageType());
        
        long endTime = System.currentTimeMillis();
        System.out.println(request.getPageType() + "页面智能建议生成完成，耗时: " + (endTime - startTime) + "ms");
        
        return result;
    }
    
    /**
     * 获取市场趋势数据
     */
    private List<String> getMarketTrends(CareerAdviceRequest request) {
        System.out.println("正在获取市场趋势数据...");
        List<String> trends = new ArrayList<>();
        
        // 查询条件
        Query query = new Query();
        if (request.getCity() != null && !request.getCity().isEmpty()) {
            query.addCriteria(Criteria.where("工作城市").is(request.getCity()));
        }
        
        // 获取职位数据，限制查询数量提高速度
        query.limit(800);
        List<Job> recentJobs = mongoTemplate.find(query, Job.class);
        System.out.println("查询到职位数量: " + recentJobs.size());
        
        // 提取热门技能
        Map<String, Integer> skillCountMap = new HashMap<>();
        for (Job job : recentJobs) {
            List<String> skills = SkillExtractor.extractSkills(job.get职位名字());
            for (String skill : skills) {
                skillCountMap.put(skill, skillCountMap.getOrDefault(skill, 0) + 1);
            }
        }
        
        // 按频率排序取前10个热门技能
        List<String> hotSkills = skillCountMap.entrySet().stream()
                .sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
                .limit(10)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());
        
        trends.add("当前热门技能: " + String.join(", ", hotSkills));
        
        // 提取目标职位的薪资范围（如果有）
        if (request.getTargetPosition() != null && !request.getTargetPosition().isEmpty()) {
            Query positionQuery = new Query(Criteria.where("职位名字").regex(request.getTargetPosition()));
            positionQuery.limit(50); // 限制查询数量
            List<Job> targetJobs = mongoTemplate.find(positionQuery, Job.class);
            
            if (!targetJobs.isEmpty()) {
                System.out.println("找到目标职位数量: " + targetJobs.size());
                double avgSalary = targetJobs.stream()
                        .mapToDouble(job -> {
                            String salary = job.get薪资待遇();
                            // 简单处理：提取数字并取平均值
                            if (salary != null && salary.contains("k") && salary.contains("-")) {
                                String[] parts = salary.split("-");
                                if (parts.length >= 2) {
                                    try {
                                        double lower = Double.parseDouble(parts[0].replaceAll("[^0-9.]", ""));
                                        double upper = Double.parseDouble(parts[1].replaceAll("[^0-9.]", ""));
                                        return (lower + upper) / 2;
                                    } catch (NumberFormatException e) {
                                        return 0;
                                    }
                                }
                            }
                            return 0;
                        })
                        .filter(value -> value > 0)
                        .average()
                        .orElse(0);
                
                if (avgSalary > 0) {
                    trends.add("目标职位平均薪资: " + String.format("%.1f", avgSalary) + "k");
                }
            }
        }
        
        return trends;
    }
    
    /**
     * 构建职业建议提示词
     */
    private String buildCareerAdvicePrompt(CareerAdviceRequest request, List<String> marketTrends) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("作为职业规划顾问，请针对以下个人信息提供职业发展建议:\n\n");
        prompt.append("技能: ").append(String.join(", ", request.getSkills())).append("\n");
        prompt.append("学历: ").append(request.getEducation()).append("\n");
        prompt.append("经验: ").append(request.getExperience()).append("\n");
        
        if (request.getTargetPosition() != null && !request.getTargetPosition().isEmpty()) {
            prompt.append("目标职位: ").append(request.getTargetPosition()).append("\n");
        }
        
        if (request.getCareerGoal() != null && !request.getCareerGoal().isEmpty()) {
            prompt.append("职业目标: ").append(request.getCareerGoal()).append("\n");
        }
        
        if (request.getCity() != null && !request.getCity().isEmpty()) {
            prompt.append("城市: ").append(request.getCity()).append("\n");
        }
        
        if (!marketTrends.isEmpty()) {
            prompt.append("\n市场趋势数据:\n");
            for (String trend : marketTrends) {
                prompt.append("- ").append(trend).append("\n");
            }
        }
        
        prompt.append("\n请按以下格式给出建议（内容精炼但保留重要细节）:\n");
        prompt.append("1. 总体建议: [总体职业发展方向和建议]\n");
        prompt.append("2. 建议学习的技能: [3-5个技能，每个包含名称、原因、难度级别]\n");
        prompt.append("3. 潜在职位机会: [3-5个适合的职位]\n");
        prompt.append("4. 学历建议: [是否需要提升学历，如何提升]\n");
        prompt.append("5. 职业路径: [未来3-5年的职业发展路径]\n");
        prompt.append("6. 市场洞察: [当前人才市场对此类人才的需求情况]\n");
        
        return prompt.toString();
    }
    
    /**
     * 解析职业建议响应
     */
    private CareerAdviceVO parseCareerAdviceResponse(String llmResponse, CareerAdviceRequest request) {
        System.out.println("开始解析职业建议响应...");
        CareerAdviceVO advice = new CareerAdviceVO();
        
        try {
            // 提取总体建议
            String overallAdvice = extractSection(llmResponse, "总体建议", "建议学习的技能");
            if (overallAdvice != null) {
                System.out.println("解析到总体建议，长度: " + overallAdvice.trim().length() + " 字符");
                advice.setOverallAdvice(overallAdvice.trim());
            }
            
            // 提取技能建议
            String skillsSection = extractSection(llmResponse, "建议学习的技能", "潜在职位机会");
            List<CareerAdviceVO.SkillAdvice> skillsToLearn = new ArrayList<>();
            if (skillsSection != null) {
                String[] skillItems = skillsSection.split("\n");
                for (String item : skillItems) {
                    if (item.trim().isEmpty() || item.contains("建议学习的技能")) continue;
                    
                    // 尝试解析技能项
                    CareerAdviceVO.SkillAdvice skillAdvice = parseSkillAdvice(item);
                    if (skillAdvice != null) {
                        skillsToLearn.add(skillAdvice);
                    }
                }
                System.out.println("解析到技能建议数量: " + skillsToLearn.size());
            }
            advice.setSkillsToLearn(skillsToLearn);
            
            // 提取潜在职位
            String positionsSection = extractSection(llmResponse, "潜在职位机会", "学历建议");
            if (positionsSection == null) {
                positionsSection = extractSection(llmResponse, "潜在职位机会", "学历提升建议");
            }
            
            List<String> positions = new ArrayList<>();
            if (positionsSection != null) {
                String[] positionItems = positionsSection.split("\n");
                for (String item : positionItems) {
                    if (item.trim().isEmpty() || item.contains("潜在职位机会")) continue;
                    
                    // 清理格式
                    String position = item.replaceAll("^[-\\d.\\s]+", "").trim();
                    if (!position.isEmpty()) {
                        positions.add(position);
                    }
                }
                System.out.println("解析到潜在职位数量: " + positions.size());
            }
            advice.setPotentialPositions(positions);
            
            // 提取学历建议
            String educationAdvice = extractSection(llmResponse, "学历建议", "职业路径");
            if (educationAdvice == null) {
                educationAdvice = extractSection(llmResponse, "学历提升建议", "职业路径建议");
            }
            
            if (educationAdvice != null) {
                System.out.println("解析到学历建议");
                advice.setEducationAdvice(educationAdvice.trim());
            }
            
            // 提取职业路径建议
            String careerPathAdvice = extractSection(llmResponse, "职业路径", "市场洞察");
            if (careerPathAdvice == null) {
                careerPathAdvice = extractSection(llmResponse, "职业路径建议", "市场洞察");
            }
            
            if (careerPathAdvice != null) {
                System.out.println("解析到职业路径建议");
                advice.setCareerPathAdvice(careerPathAdvice.trim());
            }
            
            // 提取市场洞察
            String marketInsight = extractSection(llmResponse, "市场洞察", null);
            if (marketInsight != null) {
                System.out.println("解析到市场洞察");
                advice.setMarketInsight(marketInsight.trim());
            }
        } catch (Exception e) {
            System.err.println("解析职业建议响应出错: " + e.getMessage());
            e.printStackTrace();
            throw new RuntimeException("解析AI响应失败: " + e.getMessage() + "\n原始响应: " + llmResponse.substring(0, Math.min(100, llmResponse.length())) + "...", e);
        }
        
        return advice;
    }
    
    /**
     * 解析技能建议项
     */
    private CareerAdviceVO.SkillAdvice parseSkillAdvice(String skillItem) {
        // 移除序号前缀
        String cleanItem = skillItem.replaceAll("^[-\\d.\\s]+", "").trim();
        
        // 尝试提取技能名称
        int colonIndex = cleanItem.indexOf(":");
        int dashIndex = cleanItem.indexOf("-");
        int separatorIndex = -1;
        
        if (colonIndex != -1 && (dashIndex == -1 || colonIndex < dashIndex)) {
            separatorIndex = colonIndex;
        } else if (dashIndex != -1) {
            separatorIndex = dashIndex;
        }
        
        if (separatorIndex != -1) {
            String skillName = cleanItem.substring(0, separatorIndex).trim();
            String description = cleanItem.substring(separatorIndex + 1).trim();
            
            // 提取信息
            String reason = description;
            String difficulty = "中级"; // 默认
            String learningPath = "网络课程和实践项目"; // 默认
            
            // 检查是否包含难度信息
            if (description.toLowerCase().contains("简单") || 
                description.toLowerCase().contains("初级") || 
                description.toLowerCase().contains("入门")) {
                difficulty = "初级";
            } else if (description.toLowerCase().contains("困难") || 
                      description.toLowerCase().contains("高级") || 
                      description.toLowerCase().contains("专家")) {
                difficulty = "高级";
            }
            
            // 检查是否包含学习路径信息
            if (description.contains("学习") || description.contains("课程") || 
                description.contains("教程") || description.contains("项目")) {
                // 尝试提取学习路径的句子
                String[] sentences = description.split("[.。]");
                for (String sentence : sentences) {
                    if (sentence.contains("学习") || sentence.contains("课程") || 
                        sentence.contains("教程") || sentence.contains("项目")) {
                        learningPath = sentence.trim();
                        break;
                    }
                }
            }
            
            return new CareerAdviceVO.SkillAdvice(skillName, reason, difficulty, learningPath);
        }
        
        return null;
    }
    
    /**
     * 构建学习资源提示词
     */
    private String buildLearningResourcePrompt(LearningResourceRequest request) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("我想学习").append(request.getSkillName()).append("技能，");
        
        if (request.getDifficulty() != null && !request.getDifficulty().isEmpty()) {
            prompt.append("水平是").append(request.getDifficulty()).append("，");
        }
        
        if (request.getResourceType() != null && !request.getResourceType().isEmpty()) {
            prompt.append("想找一些").append(request.getResourceType()).append("类型的资源。");
        } else {
            prompt.append("想找优质学习资源。");
        }
        
        prompt.append("\n推荐").append(Math.min(request.getSize(), 8)).append("个优质的资源，");
        prompt.append("按以下格式提供信息:\n\n");
        prompt.append("1. 标题: [标题]\n");
        prompt.append("   类型: [课程/书籍/视频/项目/文档]\n");
        prompt.append("   难度: [初级/中级/高级]\n");
        prompt.append("   描述: [简短描述，30-50字]\n");
        prompt.append("   链接: [资源链接或获取方式]\n");
        prompt.append("   平台: [平台名称]\n\n");
        prompt.append("2. ... 以此类推\n\n");
        
        return prompt.toString();
    }
    
    /**
     * 解析学习资源响应
     */
    private LearningResourceVO parseLearningResourceResponse(String llmResponse, LearningResourceRequest request) {
        System.out.println("开始解析学习资源响应...");
        try {
            List<LearningResourceVO.Resource> resources = new ArrayList<>();
            
            // 按编号分割响应
            String[] resourceBlocks = llmResponse.split("\\d+\\.");
            
            // 跳过第一个（通常为空或包含介绍性文字）
            for (int i = 1; i < resourceBlocks.length; i++) {
                String block = resourceBlocks[i].trim();
                if (block.isEmpty()) continue;
                
                // 解析资源信息
                LearningResourceVO.Resource resource = parseResourceBlock(block);
                if (resource != null) {
                    resources.add(resource);
                }
            }
            System.out.println("解析到资源数量: " + resources.size());
            
            // 应用分页
            int startIdx = (request.getPage() - 1) * request.getSize();
            int endIdx = Math.min(startIdx + request.getSize(), resources.size());
            
            List<LearningResourceVO.Resource> pagedResources;
            if (startIdx < resources.size()) {
                pagedResources = resources.subList(startIdx, endIdx);
            } else {
                pagedResources = new ArrayList<>();
            }
            
            return new LearningResourceVO(pagedResources, resources.size(), request.getPage(), request.getSize());
        } catch (Exception e) {
            System.err.println("解析学习资源响应出错: " + e.getMessage());
            e.printStackTrace();
            throw new RuntimeException("解析学习资源失败: " + e.getMessage() + "\n原始响应: " + llmResponse.substring(0, Math.min(100, llmResponse.length())) + "...", e);
        }
    }
    
    /**
     * 解析单个资源块
     */
    private LearningResourceVO.Resource parseResourceBlock(String block) {
        String title = extractProperty(block, "标题");
        if (title == null) {
            title = extractProperty(block, "资源标题");
        }
        
        String type = extractProperty(block, "类型");
        String difficulty = extractProperty(block, "难度");
        String description = extractProperty(block, "描述");
        String link = extractProperty(block, "链接");
        String platform = extractProperty(block, "平台");
        
        // 如果无法提取标题，尝试从第一行提取
        if (title == null || title.isEmpty()) {
            String[] lines = block.split("\n");
            if (lines.length > 0) {
                title = lines[0].trim();
            }
        }
        
        // 确保有有效的标题
        if (title == null || title.isEmpty()) {
            return null;
        }
        
        // 设置默认值
        if (type == null || type.isEmpty()) type = "未指定";
        if (difficulty == null || difficulty.isEmpty()) difficulty = "未指定";
        if (description == null || description.isEmpty()) description = "无描述";
        if (link == null || link.isEmpty()) link = "无链接";
        if (platform == null || platform.isEmpty()) platform = "未指定";
        
        return new LearningResourceVO.Resource(title, type, difficulty, description, link, platform);
    }
    
    /**
     * 提取文本中的特定部分
     */
    private String extractSection(String text, String startMarker, String endMarker) {
        int startIndex = text.indexOf(startMarker);
        if (startIndex == -1) return null;
        
        startIndex += startMarker.length();
        
        int endIndex;
        if (endMarker != null) {
            endIndex = text.indexOf(endMarker, startIndex);
            if (endIndex == -1) {
                endIndex = text.length();
            }
        } else {
            endIndex = text.length();
        }
        
        return text.substring(startIndex, endIndex).trim();
    }
    
    /**
     * 从文本中提取特定属性
     */
    private String extractProperty(String text, String propertyName) {
        String searchPattern = propertyName + ":";
        int index = text.indexOf(searchPattern);
        if (index == -1) return null;
        
        int valueStart = index + searchPattern.length();
        int valueEnd = text.indexOf("\n", valueStart);
        
        if (valueEnd == -1) {
            valueEnd = text.length();
        }
        
        return text.substring(valueStart, valueEnd).trim();
    }
    
    /**
     * 根据页面类型构建不同的提示词
     */
    private String buildPromptByPageType(PageAdviceRequest request) {
        String pageType = request.getPageType();
        Map<String, Object> data = request.getData();
        
        if (data == null) {
            data = new HashMap<>();
        }
        
        switch (pageType) {
            case "skill":
                return buildSkillAnalysisPrompt(data);
            case "salary":
                return buildSalaryAnalysisPrompt(data);
            case "education":
                return buildEducationAnalysisPrompt(data);
            case "city":
                return buildCityComparisonPrompt(data);
            default:
                throw new IllegalArgumentException("不支持的页面类型: " + pageType);
        }
    }
    
    /**
     * 技能分析页面的提示词构建
     */
    private String buildSkillAnalysisPrompt(Map<String, Object> data) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("作为技术招聘顾问，请根据以下技能市场分析数据提供建议:\n\n");
        
        // 添加技能分布数据
        if (data.containsKey("skillDistribution")) {
            SkillDistributionVO distribution = (SkillDistributionVO) data.get("skillDistribution");
            if (distribution != null && distribution.getList() != null && !distribution.getList().isEmpty()) {
                prompt.append("热门技能需求分布:\n");
                int count = 0;
                for (SkillItem item : distribution.getList()) {
                    if (count++ >= 10) break; // 最多取前10个
                    prompt.append("- ").append(item.getSkill())
                          .append(": ").append(item.getCount()).append(" 职位\n");
                }
                prompt.append("\n");
            }
        }
        
        // 添加技能组合数据
        if (data.containsKey("skillCombination")) {
            SkillCombinationVO combination = (SkillCombinationVO) data.get("skillCombination");
            if (combination != null && combination.getList() != null && !combination.getList().isEmpty()) {
                prompt.append("热门技能组合:\n");
                int count = 0;
                for (SkillCombinationItem item : combination.getList()) {
                    if (count++ >= 5) break; // 最多取前5个
                    prompt.append("- ").append(String.join(" + ", item.getSkills()))
                          .append(": ").append(item.getCount()).append(" 职位\n");
                }
                prompt.append("\n");
            }
        }
        
        // 添加基本信息
        if (data.containsKey("city")) {
            prompt.append("城市: ").append(data.get("city")).append("\n");
        }
        
        if (data.containsKey("skills")) {
            List<String> skills = (List<String>) data.get("skills");
            prompt.append("重点关注技能: ").append(String.join(", ", skills)).append("\n");
        }
        
        if (data.containsKey("education")) {
            prompt.append("学历要求: ").append(data.get("education")).append("\n");
        }
        
        if (data.containsKey("experience")) {
            prompt.append("经验要求: ").append(data.get("experience")).append("\n");
        }
        
        prompt.append("\n请根据以上技能市场数据，分析当前招聘市场对技术技能的需求情况，并按以下格式提供建议:\n");
        prompt.append("1. 市场需求: [分析这些技能的市场需求程度和趋势]\n");
        prompt.append("2. 技能组合建议: [推荐2-3个有竞争力的技能组合方案]\n");
        prompt.append("3. 学习路径: [如何系统地掌握这些技能的建议]\n");
        prompt.append("4. 职业方向: [利用这些技能可以发展的职业方向]\n");
        prompt.append("5. 技术发展趋势: [相关技术在未来的发展趋势]\n");
        
        return prompt.toString();
    }
    
    /**
     * 薪资分析页面的提示词构建
     */
    private String buildSalaryAnalysisPrompt(Map<String, Object> data) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("作为薪资分析专家，请根据以下薪资市场数据提供建议:\n\n");
        
        // 添加薪资分布数据
        if (data.containsKey("salaryDistribution")) {
            List<SalaryDistributionVO> salaryDistribution = (List<SalaryDistributionVO>) data.get("salaryDistribution");
            if (salaryDistribution != null && !salaryDistribution.isEmpty()) {
                prompt.append("薪资分布数据:\n");
                for (SalaryDistributionVO item : salaryDistribution) {
                    prompt.append("- ").append(item.getRange())
                          .append(": ").append(item.getCount()).append(" 职位\n");
                }
                prompt.append("\n");
            }
        }
        
        // 添加城市薪资对比数据
        if (data.containsKey("cityCompare")) {
            List<CityCompareVO> cityCompare = (List<CityCompareVO>) data.get("cityCompare");
            if (cityCompare != null && !cityCompare.isEmpty()) {
                prompt.append("城市薪资对比:\n");
                for (CityCompareVO item : cityCompare) {
                    prompt.append("- ").append(item.getCity())
                          .append(": 平均薪资 ").append(item.getAvg_salary()).append("k");
                    prompt.append("\n");
                }
                prompt.append("\n");
            }
        }
        
        // 添加基本信息
        if (data.containsKey("position")) {
            prompt.append("职位: ").append(data.get("position")).append("\n");
        }
        
        if (data.containsKey("cities")) {
            List<String> cities = (List<String>) data.get("cities");
            prompt.append("分析城市: ").append(String.join(", ", cities)).append("\n");
        }
        
        if (data.containsKey("experience")) {
            prompt.append("经验: ").append(data.get("experience")).append("\n");
        }
        
        if (data.containsKey("education")) {
            prompt.append("学历: ").append(data.get("education")).append("\n");
        }
        
        prompt.append("\n请根据以上薪资市场数据，分析当前招聘市场的薪资情况，并按以下格式给出建议:\n");
        prompt.append("1. 薪资水平评估: [分析市场整体薪资水平及其合理性]\n");
        prompt.append("2. 城市比较: [各城市薪资水平及生活成本比较]\n");
        prompt.append("3. 影响因素: [影响薪资水平的主要因素分析]\n");
        prompt.append("4. 薪资提升建议: [具体可行的薪资提升策略]\n");
        prompt.append("5. 未来趋势: [薪资发展趋势预测]\n");
        
        return prompt.toString();
    }
    
    /**
     * 学历分析页面的提示词构建
     */
    private String buildEducationAnalysisPrompt(Map<String, Object> data) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("作为教育与就业顾问，请根据以下学历分布数据提供建议:\n\n");
        
        // 添加学历分布数据
        if (data.containsKey("educationDistribution")) {
            List<EducationDistributionVO> distribution = (List<EducationDistributionVO>) data.get("educationDistribution");
            if (distribution != null && !distribution.isEmpty()) {
                prompt.append("学历要求分布:\n");
                double total = distribution.stream().mapToInt(EducationDistributionVO::getCount).sum();
                for (EducationDistributionVO item : distribution) {
                    double percentage = (total > 0) ? (item.getCount() / total * 100) : 0;
                    prompt.append("- ").append(item.getEducation())
                          .append(": ").append(item.getCount()).append(" 职位");
                    
                    if (percentage > 0) {
                        prompt.append(" (").append(String.format("%.1f", percentage)).append("%)");
                    }
                    prompt.append("\n");
                }
                prompt.append("\n");
            }
        }
        
        // 添加基本信息
        if (data.containsKey("education")) {
            prompt.append("主要学历: ").append(data.get("education")).append("\n");
        }
        
        if (data.containsKey("position")) {
            prompt.append("目标职位: ").append(data.get("position")).append("\n");
        }
        
        if (data.containsKey("city")) {
            prompt.append("城市: ").append(data.get("city")).append("\n");
        }
        
        prompt.append("\n请根据以上学历分布数据，分析当前招聘市场对学历的要求情况，并按以下格式给出建议:\n");
        prompt.append("1. 学历价值评估: [分析不同学历在就业市场的价值]\n");
        prompt.append("2. 学历与薪资关系: [学历如何影响薪资水平]\n");
        prompt.append("3. 学历要求趋势: [招聘市场学历要求的变化趋势]\n");
        prompt.append("4. 学历提升建议: [是否需要提升学历，如何提升]\n");
        prompt.append("5. 弥补策略: [如何用技能和经验弥补学历不足]\n");
        
        return prompt.toString();
    }
    
    /**
     * 城市对比页面的提示词构建
     */
    private String buildCityComparisonPrompt(Map<String, Object> data) {
        StringBuilder prompt = new StringBuilder();
        prompt.append("作为城市就业顾问，请对以下城市就业数据进行分析并提供建议:\n\n");
        
        // 添加城市对比数据
        if (data.containsKey("cityCompare")) {
            List<CityCompareVO> cityCompare = (List<CityCompareVO>) data.get("cityCompare");
            if (cityCompare != null && !cityCompare.isEmpty()) {
                prompt.append("城市薪资对比:\n");
                for (CityCompareVO item : cityCompare) {
                    prompt.append("- ").append(item.getCity())
                          .append(": 平均薪资 ").append(item.getAvg_salary()).append("k");
                    prompt.append("\n");
                }
                prompt.append("\n");
            }
        }
        
        // 添加城市职位数量数据
        if (data.containsKey("cityJobCounts")) {
            Map<String, Integer> cityJobCounts = (Map<String, Integer>) data.get("cityJobCounts");
            if (cityJobCounts != null && !cityJobCounts.isEmpty()) {
                prompt.append("城市职位总量:\n");
                for (Map.Entry<String, Integer> entry : cityJobCounts.entrySet()) {
                    prompt.append("- ").append(entry.getKey())
                          .append(": ").append(entry.getValue()).append(" 职位\n");
                }
                prompt.append("\n");
            }
        }
        
        // 添加基本信息
        if (data.containsKey("cities")) {
            List<String> cities = (List<String>) data.get("cities");
            prompt.append("比较城市: ").append(String.join(", ", cities)).append("\n");
        }
        
        if (data.containsKey("position")) {
            prompt.append("目标职位: ").append(data.get("position")).append("\n");
        }
        
        prompt.append("\n请根据以上城市就业数据，对比分析这些城市的就业情况，并按以下格式给出建议:\n");
        prompt.append("1. 就业机会对比: [各城市的就业机会数量和质量对比]\n");
        prompt.append("2. 薪资水平对比: [各城市的薪资水平详细对比]\n");
        prompt.append("3. 生活成本考量: [各城市的生活成本与薪资的平衡分析]\n");
        prompt.append("4. 行业分布特点: [各城市的主要行业分布特点]\n");
        prompt.append("5. 发展前景: [各城市的未来发展前景预测]\n");
        prompt.append("6. 城市选择建议: [综合考虑后的城市选择建议]\n");
        
        return prompt.toString();
    }
    
    /**
     * 解析大模型回复为PageAdviceVO
     */
    private PageAdviceVO parseAdviceResponse(String llmResponse, String pageType) {
        System.out.println("开始解析" + pageType + "页面智能建议响应...");
        System.out.println("原始回复内容长度: " + llmResponse.length());
        
        PageAdviceVO adviceVO = new PageAdviceVO();
        adviceVO.setPageType(pageType);
        
        try {
            // 提取总体建议（取第一段作为总体建议）
            String[] paragraphs = llmResponse.split("\n\n");
            if (paragraphs.length > 0) {
                String firstParagraph = paragraphs[0].trim();
                if (!firstParagraph.isEmpty() && 
                    !firstParagraph.startsWith("1.") && 
                    !firstParagraph.startsWith("1、") &&
                    !firstParagraph.startsWith("1：")) {
                    adviceVO.setOverallAdvice(firstParagraph);
                    System.out.println("解析到总体建议: " + firstParagraph.substring(0, Math.min(50, firstParagraph.length())) + "...");
                }
            }
            
            // 提取各个建议点
            List<PageAdviceVO.AdvicePoint> advicePoints = new ArrayList<>();
            
            // 尝试多种格式匹配建议点
            extractAdvicePoints(llmResponse, advicePoints);
            
            adviceVO.setAdvicePoints(advicePoints);
            System.out.println("解析到建议点数量: " + advicePoints.size());
            
            // 如果没有解析到建议点，但原始回复有内容，直接将整个回复作为一个建议点
            if (advicePoints.isEmpty() && !llmResponse.trim().isEmpty()) {
                System.out.println("未能解析到结构化建议点，将整个回复作为建议");
                adviceVO.setOverallAdvice("大模型智能建议");
                
                // 尝试按段落分割
                String[] contentParagraphs = llmResponse.split("\n\n");
                for (String paragraph : contentParagraphs) {
                    if (!paragraph.trim().isEmpty()) {
                        // 提取可能的标题
                        String title = extractTitle(paragraph);
                        String content = paragraph;
                        
                        if (title != null && !title.equals(content)) {
                            advicePoints.add(new PageAdviceVO.AdvicePoint(title, content.replace(title, "").trim()));
                        } else {
                            // 没有明确标题，使用前几个字作为标题
                            String autoTitle = paragraph.length() > 10 ? 
                                paragraph.substring(0, 10) + "..." : 
                                paragraph;
                            advicePoints.add(new PageAdviceVO.AdvicePoint(autoTitle, paragraph));
                        }
                    }
                }
                
                adviceVO.setAdvicePoints(advicePoints);
                System.out.println("通过段落拆分，解析到建议点数量: " + advicePoints.size());
            }
            
        } catch (Exception e) {
            System.err.println("解析智能建议响应出错: " + e.getMessage());
            e.printStackTrace();
            // 设置一个默认的建议消息
            adviceVO.setOverallAdvice("抱歉，解析智能建议时出现问题。");
            adviceVO.getAdvicePoints().add(new PageAdviceVO.AdvicePoint("建议", llmResponse));
        }
        
        // 如果仍然没有任何建议点，添加一个默认建议
        if (adviceVO.getAdvicePoints().isEmpty()) {
            adviceVO.getAdvicePoints().add(new PageAdviceVO.AdvicePoint(
                "智能建议", 
                "系统暂时无法提供针对性建议，请稍后再试。"
            ));
        }
        
        return adviceVO;
    }
    
    /**
     * 提取各种格式的建议点
     */
    private void extractAdvicePoints(String llmResponse, List<PageAdviceVO.AdvicePoint> advicePoints) {
        // 1. 匹配形如"1. 标题: 内容"的建议点
        Pattern pattern1 = Pattern.compile("(\\d+)[.、：:]\\s*([^:\\n]+)[：:](.*?)(?=\\n\\d+[.、：:]|$)", Pattern.DOTALL);
        Matcher matcher1 = pattern1.matcher(llmResponse);
        
        while (matcher1.find()) {
            String title = matcher1.group(2).trim();
            String content = matcher1.group(3).trim();
            
            // 忽略空内容
            if (!title.isEmpty() && !content.isEmpty()) {
                advicePoints.add(new PageAdviceVO.AdvicePoint(title, content));
                System.out.println("解析到建议点(格式1): " + title);
            }
        }
        
        // 如果没有找到，尝试其他格式
        if (advicePoints.isEmpty()) {
            // 2. 匹配形如"标题:"后面跟着内容的格式
            Pattern pattern2 = Pattern.compile("([^:\\n]+)[：:](.+?)(?=\\n[^:\\n]+[：:]|$)", Pattern.DOTALL);
            Matcher matcher2 = pattern2.matcher(llmResponse);
            
            while (matcher2.find()) {
                String title = matcher2.group(1).trim();
                String content = matcher2.group(2).trim();
                
                // 过滤掉非标题的冒号用法
                if (title.length() < 30 && !title.isEmpty() && !content.isEmpty()) {
                    advicePoints.add(new PageAdviceVO.AdvicePoint(title, content));
                    System.out.println("解析到建议点(格式2): " + title);
                }
            }
        }
        
        // 3. 尝试用行号分割，每行作为一个建议点标题
        if (advicePoints.isEmpty()) {
            String[] lines = llmResponse.split("\n");
            StringBuilder currentContent = new StringBuilder();
            String currentTitle = null;
            
            for (String line : lines) {
                line = line.trim();
                if (line.isEmpty()) continue;
                
                // 如果是数字开头的行，可能是一个新标题
                if (line.matches("^\\d+[.、]\\s*.+") && line.length() < 50) {
                    // 保存之前的标题和内容
                    if (currentTitle != null && currentContent.length() > 0) {
                        advicePoints.add(new PageAdviceVO.AdvicePoint(currentTitle, currentContent.toString().trim()));
                        System.out.println("解析到建议点(格式3): " + currentTitle);
                    }
                    
                    // 开始新标题
                    currentTitle = line;
                    currentContent = new StringBuilder();
                } else if (currentTitle != null) {
                    // 这是前一个标题的内容
                    currentContent.append(line).append("\n");
                } else {
                    // 第一行，还没有标题
                    currentTitle = line;
                }
            }
            
            // 添加最后一个
            if (currentTitle != null && currentContent.length() > 0) {
                advicePoints.add(new PageAdviceVO.AdvicePoint(currentTitle, currentContent.toString().trim()));
                System.out.println("解析到建议点(格式3): " + currentTitle);
            }
        }
    }
    
    /**
     * 从段落中提取可能的标题
     */
    private String extractTitle(String paragraph) {
        // 1. 检查是否有明确的数字编号
        Pattern numberPattern = Pattern.compile("^\\d+[.、：:]\\s*([^\\n]+)");
        Matcher numberMatcher = numberPattern.matcher(paragraph);
        if (numberMatcher.find()) {
            return numberMatcher.group(0);
        }
        
        // 2. 检查是否有冒号分隔的标题
        int colonIndex = paragraph.indexOf(":");
        int chineseColonIndex = paragraph.indexOf("：");
        int actualIndex = -1;
        
        if (colonIndex != -1 && chineseColonIndex != -1) {
            actualIndex = Math.min(colonIndex, chineseColonIndex);
        } else if (colonIndex != -1) {
            actualIndex = colonIndex;
        } else if (chineseColonIndex != -1) {
            actualIndex = chineseColonIndex;
        }
        
        if (actualIndex != -1 && actualIndex < 30) {
            return paragraph.substring(0, actualIndex + 1).trim();
        }
        
        return null;
    }
    
    /**
     * 获取各页面的核心数据
     */
    private Map<String, Object> getPageData(String pageType) {
        Map<String, Object> data = new HashMap<>();
        
        try {
            switch (pageType) {
                case "skill":
                    getSkillPageData(data);
                    break;
                case "salary":
                    getSalaryPageData(data);
                    break;
                case "education":
                    getEducationPageData(data);
                    break;
                case "city":
                    getCityPageData(data);
                    break;
                default:
                    System.out.println("未知页面类型: " + pageType + "，无法获取页面数据");
            }
        } catch (Exception e) {
            System.err.println("获取" + pageType + "页面数据出错: " + e.getMessage());
            e.printStackTrace();
        }
        
        return data;
    }
    
    /**
     * 获取技能分析页面的核心数据
     */
    private void getSkillPageData(Map<String, Object> data) {
        // 使用默认参数获取技能分布数据
        SkillDistributionVO skillDistribution = skillService.getSkillDistribution(null, null, null, 1, 10);
        data.put("skillDistribution", skillDistribution);
        
        // 使用默认参数获取技能组合数据
        SkillCombinationVO skillCombination = skillService.getSkillCombinations(null, null, 1, 10);
        data.put("skillCombination", skillCombination);
        
        // 提取技能列表用于建议生成
        if (skillDistribution != null && skillDistribution.getList() != null) {
            List<String> skills = skillDistribution.getList().stream()
                .map(item -> item.getSkill())
                .limit(5) // 取前5个热门技能
                .collect(Collectors.toList());
            data.put("skills", skills);
        }
    }
    
    /**
     * 获取薪资分析页面的核心数据
     */
    private void getSalaryPageData(Map<String, Object> data) {
        // 使用默认参数获取薪资分布数据
        List<SalaryDistributionVO> salaryDistribution = salaryService.getSalaryDistribution(null, null, null);
        data.put("salaryDistribution", salaryDistribution);
        
        // 使用默认参数获取三地薪资对比数据
        List<CityCompareVO> cityCompare = salaryService.getCityCompare(null, null, null);
        data.put("cityCompare", cityCompare);
        
        // 提取城市列表用于建议生成
        if (cityCompare != null && !cityCompare.isEmpty()) {
            List<String> cities = cityCompare.stream()
                .map(CityCompareVO::getCity)
                .collect(Collectors.toList());
            data.put("cities", cities);
        }
    }
    
    /**
     * 获取学历分析页面的核心数据
     */
    private void getEducationPageData(Map<String, Object> data) {
        // 使用默认参数获取学历分布数据
        List<EducationDistributionVO> educationDistribution = educationService.getEducationDistribution(null, null);
        data.put("educationDistribution", educationDistribution);
        
        // 提取主要学历类型
        if (educationDistribution != null && !educationDistribution.isEmpty()) {
            // 找出出现频率最高的学历
            EducationDistributionVO mostCommon = educationDistribution.stream()
                .max(Comparator.comparing(EducationDistributionVO::getCount))
                .orElse(null);
            
            if (mostCommon != null) {
                data.put("education", mostCommon.getEducation());
            }
        }
    }
    
    /**
     * 获取城市对比页面的核心数据
     */
    private void getCityPageData(Map<String, Object> data) {
        // 使用默认参数获取三地薪资对比数据，作为城市对比的基础数据
        List<CityCompareVO> cityCompare = salaryService.getCityCompare(null, null, null);
        data.put("cityCompare", cityCompare);
        
        // 提取城市列表用于建议生成
        if (cityCompare != null && !cityCompare.isEmpty()) {
            List<String> cities = cityCompare.stream()
                .map(CityCompareVO::getCity)
                .collect(Collectors.toList());
            data.put("cities", cities);
        }
        
        // 查询不同城市的职位数量
        if (cityCompare != null && !cityCompare.isEmpty()) {
            Map<String, Integer> cityJobCounts = new HashMap<>();
            
            for (CityCompareVO city : cityCompare) {
                Query query = new Query(Criteria.where("工作城市").is(city.getCity()));
                long count = mongoTemplate.count(query, Job.class);
                cityJobCounts.put(city.getCity(), (int) count);
            }
            
            data.put("cityJobCounts", cityJobCounts);
        }
    }
} 